﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.ExceptionHandling;
using Volo.Abp.ExceptionHandling.Localization;
using Volo.Abp.Http;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;

namespace Leo.Awesome.Infrastructure.AbpExceptionHandler
{
    public class ApplicationExceptionToErrorInfoConverter: DefaultExceptionToErrorInfoConverter
    {
        public ApplicationExceptionToErrorInfoConverter(
            IOptions<AbpExceptionLocalizationOptions> localizationOptions, 
            IStringLocalizerFactory stringLocalizerFactory, 
            IStringLocalizer<AbpExceptionHandlingResource> stringLocalizer,
            IServiceProvider serviceProvider)
           : base(localizationOptions, stringLocalizerFactory, stringLocalizer, serviceProvider)
        {
        }

        protected override void TryToLocalizeExceptionMessage(Exception exception, RemoteServiceErrorInfo errorInfo)
        {
            ILocalizeErrorMessage localizeErrorMessage = exception as ILocalizeErrorMessage;
            if (localizeErrorMessage != null)
            {
                using (IServiceScope serviceScope = base.ServiceProvider.CreateScope())
                {
                    errorInfo.Message = localizeErrorMessage.LocalizeMessage(new LocalizationContext(serviceScope.ServiceProvider));
                }

                return;
            }

            IHasErrorCode hasErrorCode = exception as IHasErrorCode;
            if (hasErrorCode == null)
            {
                return;
            }

            if (hasErrorCode.Code.IsNullOrWhiteSpace() || !hasErrorCode.Code.Contains(":"))
            {
                errorInfo.Message = hasErrorCode.Code.Split(':')[0];
                return;
            }

            string key = hasErrorCode.Code.Split(':')[0];
            Type orDefault = base.LocalizationOptions.ErrorCodeNamespaceMappings.GetOrDefault(key);
            if (orDefault == null)
            {
                return;
            }

            IStringLocalizer stringLocalizer = base.StringLocalizerFactory.Create(orDefault);
            LocalizedString localizedString = stringLocalizer[hasErrorCode.Code];
            if (localizedString.ResourceNotFound)
            {
                return;
            }

            string text = localizedString.Value;
            if (exception.Data != null && exception.Data.Count > 0)
            {
                foreach (object key2 in exception.Data.Keys)
                {
                    text = text.Replace("{" + key2?.ToString() + "}", exception.Data[key2]?.ToString());
                }
            }

            errorInfo.Message = text;
        }
    }
}
